﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace scavenger.winforms
{
    public partial class SettingsManager : Form
    {
        public static Dictionary<string, Setting> settings = new Dictionary<string, Setting>();
        //public static List<string, Setting> settings = new List<string, Setting>();

        private ListViewItem li;

        public SettingsManager()
        {
            InitializeComponent();
        }

        public static bool ReadSettings()
        {
            //TODO: Deserialize and fetch all settings.
            string path = AppDomain.CurrentDomain.BaseDirectory + "settings.dat";
            if (!File.Exists(path)) return false;

            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
            settings = (Dictionary<string, Setting>)Utils.DeserializeFromBinary(fs);
            fs.Close();
            return true;
        }

        public static void DefineSetting(string name, string defaultValue) {
            DefineSetting(name, defaultValue, SettingTypeEnum.TextBox);
        }


        public static void DefineSetting(string name,string defaultValue,SettingTypeEnum type)
        {
            settings.Add(name,new Setting(defaultValue, type) );
            //TODO: Serialize and save this setting.
            SaveSettings();
        }


        private static void SaveSettings()
        { 
            //TODO: Serialize and save all settings.
            FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "settings.dat", FileMode.Create, FileAccess.Write);
            Utils.SerializeToBinary(settings,fs);
            fs.Close();
        }

        private void SettingsManager_Load(object sender, EventArgs e)
        {
            if (settings.Count==0)
                settings.Add("item1", new Setting("test", SettingTypeEnum.TextBox));
            //fetch and display existing settings
            foreach (string key in settings.Keys)
            {
                ListViewItem li = lvwSettings.Items.Add(key, key);
                li.Tag = settings[key].type;
                li.SubItems.Add(settings[key].value);
            }

            lvwSettings.Columns[0].Width = 191;
            lvwSettings.Columns[lvwSettings.Columns.Count - 1].Width = -2;
        }

        private void lvwSettings_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
        {
        }

        private void cmdSave_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void cmdCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }


        private void cmb1_SelectedValueChanged(object sender, EventArgs e)
        {
            li.SubItems[1].Text = cmb1.Text;
            //Setting s = settings[li.Text];
            settings[li.Text].value = cmb1.Text;
            //s.value = cmb1.Text;
            cmb1.Hide();
        }

        private void cmb1_Leave(object sender, EventArgs e)
        {
            li.SubItems[1].Text = cmb1.Text;
            settings[li.Text].value = cmb1.Text;
            cmb1.Hide();
        }

        private void cmb1_KeyPress(object sender, KeyPressEventArgs e)
        {
            // Verify that the user presses ESC.
            switch (e.KeyChar)
            {
                case (char)(int)Keys.Escape:
                    {
                        // Reset the original text value, and then hide the ComboBox.
                        this.cmb1.Text = li.SubItems[1].Text;
                        this.cmb1.Visible = false;
                        break;
                    }
                case (char)(int)Keys.Enter:
                    {
                        // Hide the ComboBox.
                        this.cmb1.Visible = false;
                        break;
                    }
            }
        }

        private void SettingsManager_Resize(object sender, EventArgs e)
        {
            lvwSettings.Columns[lvwSettings.Columns.Count - 1].Width = -2;
        }

        private void lvwSettings_MouseUp(object sender, MouseEventArgs e)
        {
            // Get the item on the row that is clicked.
            li = this.lvwSettings.GetItemAt(e.X, e.Y);

            // Make sure that an item is clicked.
            if (li != null)
            {
                // Get the bounds of the item that is clicked.
                //Rectangle ClickedItem = li.Bounds;
                Rectangle ClickedItem = li.SubItems[1].Bounds;

                if (e.X < ClickedItem.Left)
                    return; //should not work for 0th column.

                // Verify that the column is completely scrolled off to the left.
                if ((ClickedItem.Left + ClickedItem.Width) < 0)
                {
                    // If the cell is out of view to the left, do nothing.
                    return;
                }

                // Verify that the column is partially scrolled off to the left.
                else if (ClickedItem.Left < 0)
                {
                    // Determine if column extends beyond right side of ListView.
                    if ((ClickedItem.Left + ClickedItem.Width) > this.lvwSettings.Width)
                    {
                        // Set width of column to match width of ListView.
                        ClickedItem.Width = this.lvwSettings.Width;
                        ClickedItem.X = 0;
                    }
                    else
                    {
                        // Right side of cell is in view.
                        ClickedItem.Width = ClickedItem.Width + ClickedItem.Left;
                        ClickedItem.X = 2;
                    }
                }
                else if (ClickedItem.Width > this.lvwSettings.Width)
                {
                    ClickedItem.Width = this.lvwSettings.Width;
                }
                else
                {
                    //ClickedItem.Width = this.lvwSettings.Columns[0].Width;
                    //ClickedItem.X = 2;
                }

                // Adjust the top to account for the location of the ListView.
                ClickedItem.Y += this.lvwSettings.Top;
                ClickedItem.X += this.lvwSettings.Left;

                // Assign calculated bounds to the ComboBox.
                this.cmb1.Bounds = ClickedItem;

                // Set default text for ComboBox to match the item that is clicked.
                this.cmb1.Text = li.SubItems[1].Text;

                // Display the ComboBox, and make sure that it is on top with focus.
                this.cmb1.Visible = true;
                this.cmb1.BringToFront();
                this.cmb1.Focus();
            }
        }

        private void SettingsManager_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.DialogResult == DialogResult.OK)
            {
                SaveSettings();
            }
            else 
            {
                ReadSettings();
            }
        }

    }

    [Serializable]
    public enum SettingTypeEnum
    {
        TextBox, ComboBox
    }

    [Serializable]
    public class Setting
    {
        public Setting(string value, SettingTypeEnum type) { this.value = value; this.type = type; }
        public string value;
        public SettingTypeEnum type;
    }

}
